var scripts = document.getElementsByTagName('script'), script = scripts[ scripts.length - 1 ]; eval(script.innerHTML);
// 取得 static的路径
script.src.replace(/(.+?)\/js\/common\.js\??(.*)/i, function(all, path, query) {
    window.STATIC = path; window.VERSION = query ? '?' + query : ''; return all;
});
// URI info
var URI  = window.URI = {};
URI.Host = (('https:' == self.location.protocol) ? 'https://' + self.location.hostname : 'http://' + self.location.hostname);
URI.Path = self.location.href.replace(/\?(.*)/, '').replace(URI.Host, '');
URI.File = URI.Path.split('/').pop();
URI.Path = URI.Path.substr(0, URI.Path.lastIndexOf('/') + 1);
URI.Url  = URI.Host + URI.Path + URI.File;

/**
 * js 跳转
 * 
 * @param url
 */
function redirect(url, args, anchor) {
    if (url) {
        // 参数
        if (args && !$.isEmptyObject(args)) {
            if (url.indexOf('?') != -1) {
                url += '&' + $.param(args);
            } else {
                url += '?' + $.param(args);
            }
        }
        // 锚点
        if (anchor) {
            url += '#' + anchor;
        }
        // 跳转
        (top || window).location.href = url.replace('&amp;', '&');
    }
}
/**
 * 等同于PHP parse_str
 *
 * @param str
 */
function parse_str(str) {
    var pairs = str.split('&'),params = {}, urldecode = function(s){
        return decodeURIComponent(s.replace(/\+/g, '%20'));
    };
    $.each(pairs,function(i,pair){
        if ((pair = pair.split('='))[0]) {
            var key  = urldecode(pair.shift());
            var value = pair.length > 1 ? pair.join('=') : pair[0];
            if (value != undefined) value = urldecode(value);

            if (key in params) {
                if (!$.isArray(params[key])) {
                    params[key] = [params[key]];
                }
                params[key].push(value);
            } else {
                params[key] = value;
            }
        }
    });
    return params;
}
/**
 * 设置cookie
 *
 * @param name
 * @param key
 * @param val
 * @param options
 */
function setCookie(name,key,val,options) {
    options = options || {};
    var cookie  = $.cookie(name),
        opts    = $.extend({ expires: 365, path: '/' }, options),
        cookies = cookie===null ? {} : parse_str(cookie);
    // 取值
    if (arguments.length == 2) {
        if (cookies[key]) return cookies[key];
        else return null;
    }
    // 赋值
    else {
        cookies[key] = val;
        return $.cookie(name, $.param(cookies), opts);
    }
}
/**
 * 取得cookie
 *
 * @param name
 * @param key
 */
function getCookie(name,key) {
    return setCookie(name,key);
}

jQuery && (function ($) {
    $.Loading_Counter = 0;
    // 设置全局 AJAX 默认选项
    $.ajaxSetup({
        beforeSend: function(xhr, s){
            $.Loading_Counter++;
            // loading
            if (s.loading !== false) {
                $.Loading = $([
                    '<div class="loading">',
                        '<div class="mask"></div>',
                        '<i class="icon">' + 'Loading, please wait ...' + '</i>',
                    '</div>'
                ].join('')).width($(window).width()).height($(window).height()).appendTo('body');
            }
            // 接管 complete
            if (s.complete) s.oriComplete = s.complete;
            // 被接管的 complete
            s.complete = function(xhr, status) {
                $.Loading_Counter--;
                if ($.Loading_Counter <= 0) {
                    if ($.Loading) $.Loading.remove();
                }
                if (s.oriComplete)
                    s.oriComplete.call(this, xhr, status);
            }
            // 接管 success
            if (s.success) {
                s.oriSuccess = s.success;
                // 自定义success
                s.success = function(data, status, xhr) {
                    var success = function(r, status, xhr) {
                        var data,code = xhr.getResponseHeader('X-LazyCMS-Code');
                        try {
                            data = $.isPlainObject(r) ? r : $.parseJSON(r);
                        } catch (e) {
                            data = r;
                        }

                        switch (code) {
                            // 提示
                            case 'Alert': case 'Error': case 'Success':
                                var message = data,
                                    timeout = xhr.getResponseHeader('X-LazyCMS-Time'),
                                    titles  = {
                                        'Alert': 'Alert', 'Error':'Error', 'Success':'Success'
                                    };
                                $.use('dialog', function(){
                                    $.alert(message, code, titles[code], function(){
                                        try { eval(xhr.getResponseHeader('X-LazyCMS-Eval')) } catch (e) {}
                                    }, timeout);
                                });
                                break;
                            // 跳转
                            case 'Redirect':
                                if (data) (self || window).location.replace(data.replace('&amp;', '&'));
                                break;
                            // 返回结果
                            case 'Return': default: data = r; break;
                        }
                        if (code && $.inArray(code, ['Return'])==-1) data = null;
                        return data;
                    }
                    var result = success.apply(this, arguments);
                    if (null !== result && s.oriSuccess) {
                        s.oriSuccess.call(this, result, status, xhr);
                    }
                }
            }
        },
        error:function(xhr,status,error) {
            if (xhr && xhr.getResponseHeader('Date')) {
                $.use('align', function(){
                    $([
                        '<div style="width:650px;" class="msg msg-strong error">',
                            '<div style="padding:10px;" class="msg-default msg-error">',
                                '<i class="msg-icon"></i>',
                                '<h4 class="msg-title">Title: ' + 'System error' + '</h4>',
                                '<div class="msg-content">',
                                    xhr.responseText,
                                '</div>',
                                '<div class="form" style="text-align:center; margin:5px;"><button class="button-silver" rel="close" type="button">' +'Close' + '</button></div>',
                            '</div>',
                        '</div>'
                    ].join(''))
                    .appendTo('body')
                    .center()
                    .find('[rel=close]').click(function(){
                        $(this).parents('div.error').remove();
                    });
                });
            }
        }
    });
    /**
     * 动态加载库
     *
     * @param modules
     * @param callback
     */
    $.use = function(modules, callback) {
        // 格式化路径
        var getPath = function(path) {
            if (path.charAt(0) == '/' || path.substr(0,7) == 'http://') {
                return path + window.VERSION;
            } else {
                return window.STATIC + '/' + path + window.VERSION
            }
        };
        // 解析依赖关系
        var get_paths = function(modules) {
            var name, module; modules = $.isArray(modules) ? modules : modules.split(',');
            for(var i=0; i < modules.length; i++) {
                name = $.trim(modules[i]); module = $.use.modules[name];
                // 首次加载
                if (module && !$.use.included[name]) {
                    // 存在依赖关系
                    if (module['requires'] && $.isArray(module['requires'])) {
                        get_paths(module['requires']);
                    }
                    // js
                    if (module['path']) {
                        paths.js.push(getPath(module['path']));
                    }
                    // css
                    if (module['css']) {
                        paths.css.push(getPath(module['css']));
                    }
                    $.use.included[name] = true;
                }
            }
        }
        // 所有文件
        var paths = {js:[],css:[]}; get_paths(modules);
        // 加载CSS
        for(var i=0; i < paths.css.length; i++) {
            $('head:first').append('<link href="' + paths.css[i] +'" rel="stylesheet" type="text/css" />');
        }
        // 加载JS
        var getScript = function(callback) {
            var path = paths.js.shift();
            if (path) {
                $.ajax({
                    cache:true, loading:false, url:path, dataType:'script', success:function(){
                        getScript(callback);
                    }
                });
            } else {
                if ($.isFunction(callback)) callback();
            }
        };
        return getScript(callback);
    };
    /**
     * 扩展的添加方法
     */
    $.extend($.use, {
        modules:{}, included:{},
        add: function(modules) {
            return $.use.modules = $.extend($.use.modules, modules);
        }
    });
    // 取得最大的zIndex
    $.fn.maxIndex = function(){
        var max = 0, index;
        this.each(function(){
            index = $(this).css('z-index');
            index = isNaN(parseInt(index)) ? 0 : index;
            max = Math.max(max, index);
        });
        return max;
    };
    /**
     * ajax submit
     *
     * @param callback
     * @param dataType
     */
    $.fn.ajaxSubmit = function(callback, dataType){
        var before;
        if (callback && $.type(callback) == 'string')
            dataType = callback;
        else if(callback && $.isPlainObject(callback)) {
            before = callback.before;
            callback = callback.callback;
            dataType = dataType || callback.type;
        }
        dataType = dataType || 'html';

        return this.each(function(){
            var self = $(this), button;

            if (!$.isFunction(before)) before = function(){
                $('input + div.msg', self).remove();
            };

            if (!$.isFunction(callback)) callback = function(r){
                var self = this; if (!$.isArray(r)) return ;
                $.each(r,function(i){
                    $('[name=' + this.id + ']', self).after([
                    '&nbsp; <div class="msg msg-weak msg-inline">',
                        '<div class="msg-default msg-error">',
                            '<i class="msg-icon"></i>',
                            '<div class="msg-content">' + this.text + '</div>',
                        '</div>',
                    '</div>'].join(''));
                });
            };
            
            $('button[type=submit]', self).click(function(){
                button = $(this);
            });
            
            self.submit(function(){
                // 禁用按钮
                button.attr('disabled',true);
                // 取得 action 地址
                var url = self.attr('action'); if (!url) url = self.location.href;
                // 执行前置函数
                if ($.isFunction(before)) before.call(self, button);
                // 数据
                var frm_data = self.serializeArray(),
                    btn_name = button.attr('name'),
                    btn_val  = button.val();
                if (btn_name) {
                    frm_data.push({name: btn_name, value: btn_val});
                }
                // ajax submit
                var submit = function() {
                    $.ajax({
                        cache: false, url: url, dataType: dataType, data: frm_data,
                        type: self.attr('method') && self.attr('method').toUpperCase() || 'POST',
                        success: function(data, status, xhr){
                            if ($.isFunction(callback)) callback.call(self, data, status, xhr);
                        },
                        complete: function(xhr){
                            button.attr('disabled', false);
                        }
                    });
                };
                // delete confirm
                if (btn_val == 'delete') {
                    $.use('dialog', function(){
                        $.confirm('Confirm Delete?', function(r){
                            if (r) {
                                submit();
                            } else {
                                button.attr('disabled', false);
                            }
                        });
                    });
                } else {
                    submit();
                }
                return false;
            });
        });
    };
    /**
     * 记忆功能
     */
    $.fn.remember = function() {
        var name = URI.File.substr(0, URI.File.lastIndexOf('.')),
            self = this, opts = { path: URI.Path };
        // 下拉框处理
        $('select[cookie=true]', this).each(function(i){
            var s = getCookie(name + '_select', 's' + i);
            if (s !== null) {
                $('option:selected', this).attr('selected', false);
                $('option[value="' + s + '"]', this).attr('selected', true);
            }
        });
        if (!$(document).data('select[cookie=true]')) {
            $(document).data('select[cookie=true]', true);
            $('select[cookie=true]', this).live('click', function(){
                setCookie(name + '_select', 's' + $('select[cookie=true]', self).index(this), this.value, opts);
            });
        }
        // 多选处理
        $('input:checkbox[cookie=true]', this).each(function(i){
            var c = getCookie(name + '_checkbox', 'c' + i),
                auto = $(this).attr('autocomplete');
            if (auto != 'off' && c !== null) {
                this.checked = c == 'true';
            }
        });
        if (!$(document).data('input:checkbox[cookie=true]')) {
            $(document).data('input:checkbox[cookie=true]', true);
            $('input:checkbox[cookie=true]', this).live('click', function(){
                if ($(this).attr('autocomplete') != 'off') {
                    setCookie(name + '_checkbox', 'c' + $('input:checkbox[cookie=true]', self).index(this), this.checked, opts);
                }
            });
        }
        return this;
    }
    /**
     * sprintf and vsprintf for jQuery
     * somewhat based on http://jan.moesen.nu/code/javascript/sprintf-and-printf-in-javascript/
     *
     * Copyright (c) 2008 Sabin Iacob (m0n5t3r) <iacobs@m0n5t3r.info>
     * This program is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * @license http://www.gnu.org/licenses/gpl.html
     * @project jquery.sprintf
     */
	var formats = {
		'b': function(val) {return parseInt(val, 10).toString(2);},
		'c': function(val) {return String.fromCharCode(parseInt(val, 10));},
		'd': function(val) {return parseInt(val, 10);},
		'u': function(val) {return Math.abs(val);},
		'f': function(val, p) {
			p = parseInt(p, 10);
			val = parseFloat(val);
			if(isNaN(p && val)) {
				return NaN;
			}
			return p && val.toFixed(p) || val;
		},
		'o': function(val) {return parseInt(val, 10).toString(8);},
		's': function(val) {return val;},
		'x': function(val) {return ('' + parseInt(val, 10).toString(16)).toLowerCase();},
		'X': function(val) {return ('' + parseInt(val, 10).toString(16)).toUpperCase();}
	};

	var re = /%(?:(\d+)?(?:\.(\d+))?|\(([^)]+)\))([%bcdufosxX])/g;

	var dispatch = function(data){
		if(data.length == 1 && typeof data[0] == 'object') { //python-style printf
			data = data[0];
			return function(match, w, p, lbl, fmt, off, str) {
				return formats[fmt](data[lbl]);
			};
		} else { // regular, somewhat incomplete, printf
			var idx = 0;
			return function(match, w, p, lbl, fmt, off, str) {
				if(fmt == '%') {
					return '%';
				}
				return formats[fmt](data[idx++], p);
			};
		}
	};
	$.extend({
		sprintf: function(format) {
			var argv = Array.apply(null, arguments).slice(1);
			return format.replace(re, dispatch(argv));
		},
		vsprintf: function(format, data) {
			return format.replace(re, dispatch(data));
		}
	});
    /*
     * JSON  - JSON for jQuery
     *
     * FILE:jquery.json.js
     *
     * Example:
     *
     * $.toJSON(Object);
     */
    $.toJSON = function(o){
        var i, v, s = $.toJSON, t;
        if (o == null) return 'null';
        t = typeof o;
        if (t == 'string') {
            v = '\bb\tt\nn\ff\rr\""\'\'\\\\';
            return '"' + o.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g, function(a, b) {
                i = v.indexOf(b);
                if (i + 1) return '\\' + v.charAt(i + 1);
                a = b.charCodeAt().toString(16);
                return '\\u' + '0000'.substring(a.length) + a;
            }) + '"';
        }
        if (t == 'object') {
            if (o instanceof Array) {
                for (i=0, v = '['; i<o.length; i++) v += (i > 0 ? ',' : '') + s(o[i]);
                return v + ']';
            }
            v = '{';
            for (i in o) v += typeof o[i] != 'function' ? (v.length > 1 ? ',"' : '"') + i + '":' + s(o[i]) : '';
            return v + '}';
        }
        return '' + o;
    };
    /**
     * Create a cookie with the given name and value and other optional parameters.
     *
     * @example $.cookie('the_cookie', 'the_value');
     * @desc Set the value of a cookie.
     * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
     * @desc Create a cookie with all available options.
     * @example $.cookie('the_cookie', 'the_value');
     * @desc Create a session cookie.
     * @example $.cookie('the_cookie', null);
     * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
     *       used when the cookie was set.
     *
     * @param String name The name of the cookie.
     * @param String value The value of the cookie.
     * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
     * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
     *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
     *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
     *                             when the the browser exits.
     * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
     * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
     * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
     *                        require a secure protocol (like HTTPS).
     * @type undefined
     *
     * @name $.cookie
     * @cat Plugins/Cookie
     * @author Klaus Hartl/klaus.hartl@stilbuero.de
     */
    /**
     * Get the value of a cookie with the given name.
     *
     * @example $.cookie('the_cookie');
     * @desc Get the value of a cookie.
     *
     * @param String name The name of the cookie.
     * @return The value of the cookie.
     * @type String
     *
     * @name $.cookie
     * @cat Plugins/Cookie
     * @author Klaus Hartl/klaus.hartl@stilbuero.de
     */
    $.cookie = function(name, value, options) {
        if (typeof value != 'undefined') { // name and value given, set cookie
            options = options || {};
            if (value === null) {
                value = '';
                options.expires = -1;
            }
            var expires = '';
            if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
                var date;
                if (typeof options.expires == 'number') {
                    date = new Date();
                    date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
                } else {
                    date = options.expires;
                }
                expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
            }
            // CAUTION: Needed to parenthesize options.path and options.domain
            // in the following expressions, otherwise they evaluate to undefined
            // in the packed version for some reason...
            var path = options.path ? '; path=' + (options.path) : '';
            var domain = options.domain ? '; domain=' + (options.domain) : '';
            var secure = options.secure ? '; secure' : '';
            document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
        } else { // only name given, get cookie
            var cookieValue = null;
            if (document.cookie && document.cookie != '') {
                var cookies = document.cookie.split(';');
                for (var i = 0; i < cookies.length; i++) {
                    var cookie = jQuery.trim(cookies[i]);
                    // Does this cookie string begin with the name we want?
                    if (cookie.substring(0, name.length + 1) == (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                    }
                }
            }
            return cookieValue;
        }
    };
    /**
     * The bgiframe is chainable and applies the iframe hack to get
     * around zIndex issues in IE6. It will only apply itself in IE6
     * and adds a class to the iframe called 'bgiframe'. The iframe
     * is appeneded as the first child of the matched element(s)
     * with a tabIndex and zIndex of -1.
     *
     * By default the plugin will take borders, sized with pixel units,
     * into account. If a different unit is used for the border's width,
     * then you will need to use the top and left settings as explained below.
     *
     * NOTICE: This plugin has been reported to cause perfromance problems
     * when used on elements that change properties (like width, height and
     * opacity) a lot in IE6. Most of these problems have been caused by
     * the expressions used to calculate the elements width, height and
     * borders. Some have reported it is due to the opacity filter. All
     * these settings can be changed if needed as explained below.
     *
     * @example $('div').bgiframe();
     * @before <div><p>Paragraph</p></div>
     * @result <div><iframe class="bgiframe".../><p>Paragraph</p></div>
     *
     * @param Map settings Optional settings to configure the iframe.
     * @option String|Number top The iframe must be offset to the top
     *      by the width of the top border. This should be a negative
     *      number representing the border-top-width. If a number is
     *      is used here, pixels will be assumed. Otherwise, be sure
     *      to specify a unit. An expression could also be used.
     *      By default the value is "auto" which will use an expression
     *      to get the border-top-width if it is in pixels.
     * @option String|Number left The iframe must be offset to the left
     *      by the width of the left border. This should be a negative
     *      number representing the border-left-width. If a number is
     *      is used here, pixels will be assumed. Otherwise, be sure
     *      to specify a unit. An expression could also be used.
     *      By default the value is "auto" which will use an expression
     *      to get the border-left-width if it is in pixels.
     * @option String|Number width This is the width of the iframe. If
     *      a number is used here, pixels will be assume. Otherwise, be sure
     *      to specify a unit. An experssion could also be used.
     *      By default the value is "auto" which will use an experssion
     *      to get the offsetWidth.
     * @option String|Number height This is the height of the iframe. If
     *      a number is used here, pixels will be assume. Otherwise, be sure
     *      to specify a unit. An experssion could also be used.
     *      By default the value is "auto" which will use an experssion
     *      to get the offsetHeight.
     * @option Boolean opacity This is a boolean representing whether or not
     *      to use opacity. If set to true, the opacity of 0 is applied. If
     *      set to false, the opacity filter is not applied. Default: true.
     * @option String src This setting is provided so that one could change
     *      the src of the iframe to whatever they need.
     *      Default: "javascript:false;"
     *
     * @name bgiframe
     * @type jQuery
     * @cat Plugins/bgiframe
     * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
     */
    $.fn.bgIframe = $.fn.bgiframe = function(s) {
        // This is only for IE6
        if ( $.browser.msie && /6.0/.test(navigator.userAgent) ) {
            s = $.extend({
                top     : 'auto', // auto == .currentStyle.borderTopWidth
                left    : 'auto', // auto == .currentStyle.borderLeftWidth
                width   : 'auto', // auto == offsetWidth
                height  : 'auto', // auto == offsetHeight
                opacity : true,
                src     : 'javascript:false;'
            }, s || {});
            var prop = function(n){ return n&&n.constructor==Number?n+'px':n; },
                html = '<iframe class="bgiframe" frameborder="0" tabindex="-1" src="'+s.src+'" '+
                           'style="display:block;position:absolute;z-index:-1;'+
                               (s.opacity !== false?'filter:Alpha(Opacity=\'0\');':'')+
                               'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+
                               'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+
                               'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+
                               'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+
                        '"/>';
            return this.each(function() {
                if ( $('> iframe.bgiframe', this).length == 0 )
                    this.insertBefore( document.createElement(html), this.firstChild );
            });
        }
        return this;
    };
})(jQuery);

/**
 * 配置插件包的依赖关系
 */
$.use.add({
    'align': { path:'js/plugins/align.js'},
    'tooltip': { path:'js/plugins/tooltip.js'},
    'dialog': { path:'js/plugins/dialog.js', requires:['align'] }
});
